﻿using blackhouse.WebNemo.Business.Groups;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace blackhouse.WebNemo.Web {
    public class HostRecordFileOperation : RecordFileOperation {

        #region Fields

        private NemoRecordFileOperation nemoFileOperation;
        private string fileLocations = String.Empty;

        #endregion

        #region Constructors

        public HostRecordFileOperation(IGroupRecord record, string column)
            : base(record, column) {
            this.nemoFileOperation = new NemoRecordFileOperation(record, column);
            this.fileLocations = this.GetFileLocations();
            if (!this.fileLocations.EndsWith(@"\"))
                this.fileLocations = this.fileLocations + @"\";
            this.fileLocations = this.SpecificFileLocations(this.fileLocations);
        }

        #endregion

        #region Methods

        private string SpecificFileLocations(string parentLocation) {
            string specFileLocations = parentLocation + this.record.BelongsToGroupId + "_" + this.column + @"\";
            DirectoryInfo sdi = new DirectoryInfo(specFileLocations);
            if (!sdi.Exists)
                sdi.Create();
            return specFileLocations;
        }

        private string GetFileLocations() {
            string location = ConfigurationManager.AppSettings["NemoHostFileLocation"];
            if (!String.IsNullOrEmpty(location)) {
                DirectoryInfo di = new DirectoryInfo(location);
                if (di.Exists)
                    return location;
            }
            location = HttpContext.Current.Server.MapPath("~/Nemo/HostFiles");
            DirectoryInfo dil = new DirectoryInfo(location);
            if (!dil.Exists)
                dil.Create();
            return dil.FullName;
        }

        public override bool SaveFile(RecordFileData data, Stream fileStream) {
            string extension = data.FileName.Split('.').Last();
            FileInfo fi = new FileInfo(this.fileLocations + record.RecordId + '.' + extension);
            if (fi.Exists)
                fi.Delete();
            if (fileStream != null) {
                using (FileStream fs = fi.Create()) {
                    if (fileStream.CanSeek)
                        fileStream.Seek(0, SeekOrigin.Begin);
                    fileStream.CopyTo(fs);
                }
            }
            using (Stream ss = this.GenerateStreamFromString(fi.FullName)) {
                this.nemoFileOperation.SaveFile(data, ss);
            }
            return true;
        }

        public Stream GenerateStreamFromString(string s) {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }

        public override byte[] GetFileData() {
            DirectoryInfo di = new DirectoryInfo(this.fileLocations);
            FileInfo[] fis = di.GetFiles(record.RecordId + ".*");
            byte[] data = null;
            if (fis.Length == 1) {
                FileInfo fi = fis[0];
                using (FileStream fs = fi.OpenRead()) {
                    data = this.ReadFully(fs);
                }
            }
            return data;
        }

        public byte[] ReadFully(Stream input) {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream()) {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        public override RecordFileData GetInfo() {
            return this.nemoFileOperation.GetInfo();
        }

        public static void CopyFilesFromDatabaseToHost(GroupRecords records, string column) {
            foreach (GroupRecord record in records) {
                CopyFileFromDatabaseToHost(record, column);
            }
        }

        private static void CopyFileFromDatabaseToHost(GroupRecord record, string column) {
            NemoRecordFileOperation nfo = new NemoRecordFileOperation(record, column);
            HostRecordFileOperation hfo = new HostRecordFileOperation(record, column);
            if (!nfo.GetInfo().Exist) return;
            using (MemoryStream ms = new MemoryStream(nfo.GetFileData())) {
                hfo.SaveFile(nfo.GetInfo(), ms);
            }
        }

        #endregion

    }
}
